4 // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
6 // The use and distribution terms for this software are contained in the file
7 // named license.txt, which can be found in the root of this distribution.
8 // By using this software in any fashion, you are agreeing to be bound by the
9 // terms of this license.
11 // You must not remove this notice, or any other, from this software.
15 // ACTION.C -- routines called by the parser
18 // This module contains the routines called during parsing of a makefile.
25 void startNameList(void);
26 void makeRule(STRINGLIST
*, BOOL fBatch
);
27 void makeTarget(char*, BOOL
, BUILDBLOCK
**);
28 void appendPseudoTargetList(STRINGLIST
**, STRINGLIST
*);
29 void clearSuffixes(void);
30 BOOL
doSpecial(char*);
31 BUILDLIST
* makeBuildList(BUILDBLOCK
*);
32 char * nextComponent(char **);
34 // created by endNameList() & freed by assignBuildCommands(). In use because
35 // although global 'list' has this list is used by too many routines and the
36 // complete sequence of actions on 'list' is unknown
38 STRINGLIST
* targetList
; // corr to a dependency block
41 // makeName -- create copy of a name seen by lexer
44 // Create a copy of a macro or 1st name in a target/dependency list. It also
45 // does the groundwork for expansion of macros in name and saves values.
47 // Assumes: That the lexical routines save the token in buf
50 // name -- the pointer to the copy created, gets allocated memory
51 // macros -- the list of macro values in name. Used later by startNameList()
52 // to expand macros in name and get expanded target name.
55 // buf -- the lexical routines return a token in this
58 // The token in buf could be part of a macrodefinition or a target list. The
59 // next token determines if it is a macrodefn or a targetlist we are parsing.
60 // The next token would overwrite the current token and so it is saved in name.
65 findMacroValues(buf
, ¯os
, NULL
, NULL
, 0, 0, 0);
66 name
= makeString(buf
);
74 STRINGLIST
*p
; // from lexer
78 SET(actionFlags
, A_TARGET
);
82 if (ON(actionFlags
, A_TARGET
)) {
84 if (ON(actionFlags
, A_RULE
))
85 makeError(currentLine
, TOO_MANY_RULE_NAMES
);
86 makeError(currentLine
, MIXED_RULES
);
89 p
= makeNewStrListElement();
90 if (ON(actionFlags
, A_STRING
)) { // we collect macros
91 p
->text
= string
; // for dependents &
92 string
= NULL
; // build lines for
93 } else // non-implicit rules
94 p
->text
= makeString(buf
);
96 NewList
= p
; // build lines for
97 if (OFF(actionFlags
, A_RULE
) // rules get expanded
98 || ON(actionFlags
, A_TARGET
)) // after entire make-
100 findMacroValues(p
->text
, ¯os
, NULL
, NULL
, 0, 0, 0); // file parsed
103 if (ON(actionFlags
, A_TARGET
)) {
105 expandFileNames("$", &NewList
, ¯os
);
106 expandFileNames("*?", &NewList
, NULL
);
107 while ((macros
= p
)) {
109 FREE_STRINGLIST(macros
);
113 appendItem(&list
, NewList
);
117 // startNameList -- puts in the first element into list
121 // Purpose: Puts in the first name seen into a list
123 // Errors/Warnings: TARGET_MACRO_IS_NULL -- if the macro used as a target expands to null
126 // The global 'list' is originally a null list, & the global 'macro' points to
127 // a list of values used for expanding the macros in global 'name'.
130 // list -- the list of names; set to contain the first name here or to a
131 // list of values if 'name' contains a macro invocation.
132 // macros -- the list of values reqd for macro expansion; the list is
133 // freed and macros is made NULL
134 // currentFlags -- the flags for current target; set to global flags
135 // actionFlags -- determine actions to be done; if the name is a rule then set
139 // name -- the first name seen in a list of names.
140 // flags -- the global flags setup by the options specified
141 // actionFlags -- if handling targets then no error as we have > 1 target
144 // If there is more than one target then actionFlags has A_TARGET flag set and
145 // startNameList() is called from addItemToList. In this case don't flag error.
152 currentFlags
= flags
; // set flags for cur target
153 p
= makeNewStrListElement();
155 list
= p
; // list contains name
157 expandFileNames("$", &list
, ¯os
); // expand macros in name
158 expandFileNames("*?", &list
, NULL
); // expand wildcards
159 while ((macros
= p
)) { // free macro list
161 FREE_STRINGLIST(macros
);
163 if (!list
&& OFF(actionFlags
, A_TARGET
))
164 makeError(line
, TARGET_MACRO_IS_NULL
, name
); // target null & 1 target
166 if (list
&& isRule(list
->text
))
167 SET(actionFlags
, A_RULE
);
171 // endNameList -- semantic actions when a list is fully seen
174 // When the parser has seen an entire list then it needs to do some semantic
175 // actions. It calls endNameList() to do these actions. The action depends on
176 // the values in certain globals.
178 // Modifies Globals: actionFlags --
181 // name -- The first element seen (if non null)
182 // actionFlags -- The flag determining semantic & data structure actions
183 // buf -- The delimiter seen after list
184 // list -- The list of elements seen
189 if (name
) { // if only one name to left of :
190 startNameList(); // it hasn't been put in list yet
193 CLEAR(actionFlags
, A_TARGET
); // clear target flag
196 SET(currentFlags
, F2_DOUBLECOLON
); // so addItemToList()
198 if (!list
) // won't expand names
199 makeError(currentLine
, SYNTAX_NO_TARGET_NAME
); // of dependents
201 if (ON(actionFlags
, A_RULE
)) {
203 // A rule with a doublecolon on the dependency line
204 // is a "batch rule", i.e., a rule that applies the
205 // command block in batch mode for all affected
207 fBatch
= !!(ON(currentFlags
, F2_DOUBLECOLON
));
208 makeRule(list
, fBatch
);
209 FREE_STRINGLIST(list
);
211 else if (!(list
->next
) && doSpecial(list
->text
)) { // special pseudotarget ...
212 FREE(list
->text
); // don't need ".SUFFIXES" etc
213 FREE_STRINGLIST(list
);
215 else // regular target
219 // We are now looking for a dependent
220 SET(actionFlags
, A_DEPENDENT
);
230 if (!_tcsicmp(s
, silent
)) {
231 SET(actionFlags
, A_SILENT
);
236 if (!_tcsicmp(s
, ignore
)) {
237 SET(actionFlags
, A_IGNORE
);
241 else if (!_tcscmp(s
, suffixes
)) {
242 SET(actionFlags
, A_SUFFIX
);
245 else if (!_tcscmp(s
, precious
)) {
246 SET(actionFlags
, A_PRECIOUS
);
256 STRINGLIST
**sourceList
,
257 STRINGLIST
**macroList
262 STRINGLIST
*p
; // Main list pointer
263 STRINGLIST
*pNew
, // Pointer to new list
264 *pBack
; // Pointer to one element back
265 char *saveText
= NULL
;
267 for (pBack
= NULL
, p
= *sourceList
; p
;) {
269 // If no expand-character is found, continue to next list element.
270 if (!_tcspbrk(p
->text
, string
)) {
276 // Either expand macros or wildcards.
277 if (*string
== '$') {
278 t
= expandMacros(p
->text
, macroList
);
282 // If the wildcard string does not expand to anything, go to
283 // next list elment. Do not remove p from the original list
284 // else we must check for null elsewhere.
286 // -- do not attempt to expand wildcards that
287 // occur in inference rules
289 if (isRule(p
->text
) || (pNew
= expandWildCards(p
->text
)) == NULL
) {
297 // At this point we have a list of expanded names to replace p with.
299 pBack
->next
= p
->next
;
303 *sourceList
= p
->next
;
308 if (*string
== '$') { // if expanding macros
310 if ((s
= nextComponent(&str
))) {
311 do { // put expanded names
312 pNew
= makeNewStrListElement(); // at front of list
313 pNew
->text
= makeString(s
); // so we won't try to
314 prependItem(sourceList
, pNew
); // re-expand them
317 } while ((s
= nextComponent(&str
)));
322 else if (pNew
) { // if matches for * ?
324 for (pBack
= pNew
; pBack
->next
; pBack
= pBack
->next
)
326 appendItem(&pNew
, *sourceList
); // put at front of old list
334 // nextComponent - returns next component from expanded name
336 // Scope: Local (used by expandFilenames)
339 // Given a target string (target with macros expanded) this function returns a
340 // name component. Previously _tcstok(s, " \t") was used but with the advent of
341 // quoted filenames this is no good.
343 // Input: szExpStr - the target name with macros expanded
345 // Output: Returns pointer to next Component; NULL means no more components left.
347 // Assumes: That that two quoted strings are seperated by whitespace.
358 while (WHITESPACE(*t
))
366 for (; *++t
&& *t
!= '"';)
369 for (; *t
&& *t
!= ' ' && *t
!= '\t'; t
++)
373 if (WHITESPACE(*t
)) {
375 } else if (*t
== '"') {
377 if(*t
=='\0') t
--; // If this is the end of the string, backup a byte, so we don't go past next time
378 else *t
= '\0'; // else stop here for this time.
380 // If at end of string then backup a byte so that next time we don't go past
389 // append dependents to existing ones (if any)
393 const char *which
= NULL
;
395 if (ON(actionFlags
, A_DEPENDENT
))
396 CLEAR(actionFlags
, A_DEPENDENT
);
398 if (ON(actionFlags
, A_RULE
)) {
400 makeError(currentLine
, DEPENDENTS_ON_RULE
);
402 else if (ON(actionFlags
, A_SILENT
) || ON(actionFlags
, A_IGNORE
)) {
404 if (ON(actionFlags
, A_SILENT
))
406 else if (ON(actionFlags
, A_IGNORE
))
408 makeError(currentLine
, DEPS_ON_PSEUDO
, which
);
411 else if (ON(actionFlags
, A_SUFFIX
)) {
415 appendPseudoTargetList(&dotSuffixList
, list
);
417 else if (ON(actionFlags
, A_PRECIOUS
)) {
419 appendPseudoTargetList(&dotPreciousList
, list
);
422 block
= makeNewBuildBlock();
423 block
->dependents
= list
;
424 block
->dependentMacros
= macros
;
428 SET(actionFlags
, A_STRING
); // expecting build cmd
432 assignBuildCommands()
434 BOOL okToFreeList
= TRUE
;
435 BOOL fFirstTarg
= (BOOL
)TRUE
;
437 const char *which
= NULL
;
439 if (ON(actionFlags
, A_RULE
)) // no macros found yet for inference rules
440 rules
->buildCommands
= list
;
441 else if (ON(actionFlags
, A_SILENT
) ||
442 ON(actionFlags
, A_IGNORE
) ||
443 ON(actionFlags
, A_PRECIOUS
) ||
444 ON(actionFlags
, A_SUFFIX
)
447 if (ON(actionFlags
, A_SILENT
))
449 else if (ON(actionFlags
, A_IGNORE
))
451 else if (ON(actionFlags
, A_PRECIOUS
))
453 else if (ON(actionFlags
, A_SUFFIX
))
455 makeError(currentLine
, CMDS_ON_PSEUDO
, which
);
458 block
->buildCommands
= list
;
459 block
->buildMacros
= macros
;
460 block
->flags
= currentFlags
;
461 while ((p
= targetList
)) { // make a struct for each targ
462 if (doSpecial(p
->text
)) // in list, freeing list when
463 makeError(currentLine
, MIXED_TARGETS
);
464 makeTarget(p
->text
, fFirstTarg
, &block
); // done, don't free name
465 if (!makeTargets
) { // field -- it's still in use
466 makeTargets
= p
; // if no targs given on cmdlin
467 okToFreeList
= FALSE
; // put first target(s) from
468 } // mkfile in makeTargets list
469 targetList
= p
->next
; // (makeTargets defined in
470 if (okToFreeList
) // nmake.c)
473 fFirstTarg
= (BOOL
)FALSE
;
483 // makeMacro -- define macro with name and string taken from global variables
486 // fInheritUserEnv set to TRUE
489 // Calls putMacro() to place expanded Macros in the NMAKE table. By setting
490 // fInheritUserEnv those definitions that change Environment variables are
491 // inherited by the environment.
499 if (_tcschr(name
, '$')) { // expand name
501 t
= expandMacros(name
, ¯os
); // name holds result
502 if (!*t
) // error if macro to left of = is undefined
503 makeError(currentLine
, SYNTAX_NO_MACRO_NAME
);
504 while ((macros
= q
)) {
506 FREE_STRINGLIST(macros
);
512 for (t
= name
; *t
&& MACRO_CHAR(*t
); t
= _tcsinc (t
)) // Check for illegal chars
516 makeError(currentLine
, SYNTAX_BAD_CHAR
, *t
);
518 fInheritUserEnv
= (BOOL
)TRUE
;
520 // Put Env Var in Env & macros in table.
522 if (!putMacro(name
, string
, 0)) {
526 name
= string
= NULL
;
530 // defineMacro -- check macro's syntax for illegal chars., then define it
532 // actions: check all of macro's characters
533 // if one's bad and it's an environment macro, bag it
535 // call putMacro to do the real work
537 // can't use macro invocation to left of = in macro def from commandline
538 // it doesn't make sense to do that, because we're not in a makefile
539 // the only way to get a comment char into the makefile w/o having it really
540 // mark a comment is to define a macro A=# on the command line
544 char *s
, // commandline or env definitions
551 for (u
= s
; *u
&& MACRO_CHAR(*u
); u
= _tcsinc(u
)) // check for illegal
554 if (ON(flags
, M_ENVIRONMENT_DEF
)) { // ignore bad macros
557 makeError(currentLine
, SYNTAX_BAD_CHAR
, *u
); // chars, bad syntax
559 return(putMacro(s
, t
, flags
)); // put macro in table
563 // putMacro - Put the macro definition into the Macro Table / Environmnet
569 // putMacro() inserts a macro definition into NMAKE's macro table and also into
570 // the environment. If a macro name is also an environment variable than its
571 // value is inherited into the environment. While replacing older values by new
572 // values NMAKE needs to follow the precedence of macro definitions which is
573 // as per the notes below.
576 // name - Name of the macro
577 // value - Value of the macro
578 // flags - Flags determining Precedence of Macro definitions (see Notes)
583 // OUT_OF_ENV_SPACE - If putenv() returns failure in adding to the environment.
586 // Whatever it assumes
589 // fInheritUserEnv - Set to False.
592 // fInheritUserEnv - If True then Inherit definition to the Environment.
593 // gFlags - Global Options Flag. If -e specified then Environment Vars
595 // macroTable - NMAKE's internal table of Macro Definitions.
598 // 1> If the same macro is defined in more than one place then NMAKE uses the
599 // following order of Precedence (highest to lowest) --
601 // -1- Command line definitions
602 // -2- Description file/Include file definitions
603 // -3- Environment definitions
604 // -4- TOOLS.INI definitions
605 // -5- Predefined Values (e.g. for CC, AS, BC, RC)
606 // If -e option is specified then -3- precedes -2-.
608 // 2> Check if the macro already exists in the Macro Table. If the macro is not
609 // redefinable (use order of precedence) then return. Make a new string
610 // element to hold macro's new value. If the macro does not exist then create
611 // new entry in the Macro table. Set Macro's flag to be union of Old and new
612 // values. Add the new value to macro's value entry. If a new macro then add
613 // it to the macro table. Test for Cyclic definitions.
624 BOOL defined
= FALSE
;
627 // Convert path separators to the native path separator.
628 // Do that with a copy of the original string so we don't change
630 value
= makeString(value
);
633 while ((tmp
= FindFirstPathSeparator(tmp
))) {
634 *tmp
++ = PATH_SEPARATOR_CHAR
;
639 if (ON(flags
, M_NON_RESETTABLE
)) {
641 if ((putEnvStr(name
,removeMacros(value
)) == -1))
642 makeError(currentLine
, OUT_OF_ENV_SPACE
);
644 if (fInheritUserEnv
&&
645 OFF(gFlags
, F1_USE_ENVIRON_VARS
) &&
648 if ((p
= findMacro(name
))) { // don't let user
649 if (CANT_REDEFINE(p
)) // redefine cmdline
650 return(FALSE
); // macros, MAKE, etc.
652 if ((putEnvStr(name
,removeMacros(value
)) == -1))
653 makeError(currentLine
, OUT_OF_ENV_SPACE
);
656 fInheritUserEnv
= (BOOL
)FALSE
;
657 if ((p
= findMacro(name
))) { // don't let user
658 if (CANT_REDEFINE(p
)) // redefine cmdline
659 return(FALSE
); // macros, MAKE, etc.
662 q
= makeNewStrListElement();
668 assert(p
->flags
== 0);
669 assert(p
->values
== NULL
);
673 p
->flags
&= ~M_UNDEFINED
; // Is no longer undefined
674 p
->flags
|= flags
; // Set flags to union of old and new
675 prependItem((STRINGLIST
**)&(p
->values
), (STRINGLIST
*)q
);
677 insertMacro((STRINGLIST
*)p
);
679 if (OFF(flags
, M_LITERAL
) && _tcschr(value
, '$')) { // Check for cyclic Macro Definitions
680 SET(p
->flags
, M_EXPANDING_THIS_ONE
);
681 // NULL -> don't build list
682 fSyntax
= findMacroValues(value
, NULL
, NULL
, name
, 1, 0, flags
);
683 CLEAR(p
->flags
, M_EXPANDING_THIS_ONE
);
688 p
->flags
|= M_UNDEFINED
;
690 // return TRUE since p has been added to the macro table
691 // Otherwise the caller may free name and value leaving
692 // dangling pointers in the macro table.
699 // makeRule -- makes an inference rule
705 // Allocates space for an inference rule and adds rule to the beginning of the
706 // doubly linked inference rule list. The name of the rule is also added.
709 // rule -- The name of the inference rule
710 // fBatch -- True if command block should be executed in batch mode
719 // rules -- The doubly linked inference rule list to which the rule is added
724 // The syntax of an inference rule is --
726 // {frompath}.fromext{topath}.toext: # Name of the inference rule
727 // command ... # command block of the inference rule
737 rList
= makeNewRule();
738 rList
->name
= rule
->text
;
741 // Convert path separators to the native path separator.
742 char *tmp
= rList
->name
;
743 while ((tmp
= FindFirstPathSeparator(tmp
))) {
744 *tmp
++ = PATH_SEPARATOR_CHAR
;
746 #endif // PLATFORM_UNIX
748 rList
->fBatch
= fBatch
;
749 prependItem((STRINGLIST
**)&rules
, (STRINGLIST
*)rList
);
751 rList
->next
->back
= rList
;
755 // makeTarget -- add target to targetTable
757 // actions: if no block defined, create one and initialize it
758 // make new build list entry for this target
759 // if the target's already in the table,
760 // flag error if : and :: mixed
761 // else add new buildlist object to target's current buildlist
762 // else allocate new object, initialize it, and stick it in table
775 *block
= makeNewBuildBlock();
778 build
= makeNewBldListElement();
779 build
->buildBlock
= *block
;
781 build
= makeBuildList(*block
);
783 if ((object
= findTarget(s
))) {
784 if (ON(object
->flags2
, F2_DOUBLECOLON
) != ON(currentFlags
, F2_DOUBLECOLON
))
785 makeError(currentLine
, MIXED_SEPARATORS
);
786 appendItem((STRINGLIST
**)&(object
->buildList
), (STRINGLIST
*)build
);
790 object
= makeNewObject();
792 object
->buildList
= build
;
793 object
->flags2
= currentFlags
;
794 prependItem((STRINGLIST
**)targetTable
+hash(s
, MAXTARGET
, (BOOL
)TRUE
),
795 (STRINGLIST
*)object
);
805 while ((p
= dotSuffixList
)) {
806 dotSuffixList
= dotSuffixList
->next
;
814 appendPseudoTargetList(
819 STRINGLIST
*p
, *q
, *r
;
823 if (!_tcschr(p
->text
, '$')) {
826 appendItem(pseudo
, p
);
829 t
= expandMacros(p
->text
, ¯os
);
830 while (r
!= macros
) {
835 for (u
= _tcstok(t
, " \t"); u
; u
= _tcstok(NULL
, " \t")) {
836 q
= makeNewStrListElement();
837 q
->text
= makeString(u
);
838 appendItem(pseudo
, q
);
848 // putEnvStr -- Extends putenv() standard function
851 // Library function putenv() expects one string argument of the form
853 // Most of the times when putenv() is to be used we have two strings
854 // name -- of the variable to add to the environment, and
855 // value -- to be set
856 // putEnvStr takes these 2 parameters and calls putenv with the reqd
860 // name -- of var to add to the env
861 // value -- reqd to be set
872 BOOL b
= SetEnvironmentVariableA(name
, value
);
878 // makeBuildList -- takes a build block and copies into a buildlist
881 // Routine creates a copy of a buildlist and returns a pointer to a copy.
882 // When multiple targets have the same description block then there is a
883 // need for each of them to get seperate build blocks. makeBuildList()
884 // helps achieve this by creating a copy for each target.
887 // bBlock -- the build block whose copy is to be added to a build block
890 // Returns a pointer to the copy of buildlist it creates
897 BUILDLIST
*tList
= makeNewBldListElement();
898 BUILDBLOCK
*tBlock
= makeNewBuildBlock();
900 tBlock
->dependents
= bBlock
->dependents
;
901 tBlock
->dependentMacros
= bBlock
->dependentMacros
;
902 tBlock
->buildCommands
= bBlock
->buildCommands
;
903 tBlock
->buildMacros
= bBlock
->buildMacros
;
904 tBlock
->flags
= bBlock
->flags
;
905 tBlock
->dateTime
= bBlock
->dateTime
;
907 tList
->buildBlock
= tBlock
;